/*	This file is part of AstroAttack.
*
*	AstroAttack is free software; you can redistribute it and/or modify
*	it under the terms of the GNU General Public License as published by
*	the Free Software Foundation; either version 2 of the License, or
*	(at your option) any later version.
*	
*	AstroAttack is distributed in the hope that it will be useful,
*	but WITHOUT ANY WARRANTY; without even the implied warranty of
*	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*	GNU General Public License for more details.
*	
*	You should have received a copy of the GNU General Public License
*	along with AstroAttack; if not, write to the Free Software
*	Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*	
*	$Id: AlienController.java 75 2007-02-20 01:14:59Z cornfused36 $
*/

/**	The AstroAttack package contains all the classes that belong to the
*	AstroAttack program.
*/
package AstroAttack;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Random;

import java.awt.geom.Point2D;
import java.awt.Point;
import java.awt.Canvas;

public class AlienController 
{
	/**	The single instance of the class. */
	private static AlienController m_ref;
	
	/**	This method returns the instance or initializes if it hasn't been
	*	initialized.
    *	@return	the instance of AlienController
	*/
	public static AlienController getAlienController()
	{
		if ( m_ref == null )
			m_ref = new AlienController();
		return m_ref;
	}
	
	private ArrayList<Alien> ents;
	private int canvass, entering;
	private int [] enterList;
	private int [] row;
	private int [] rowPos;
	private String [] alien;
	private ImageCache ic;
	private Canvas canvas;
	private int block;
	private boolean first;
	private Random rg;
	private BulletController m_bc;
	private WorldManager m_wm;
	public AlienController()
	{
		m_ref = this;
		canvas = Engine.getEngine().getCanvas();
		ents = new ArrayList<Alien>();
		canvass = 0;
		entering = 0;
		rowPos = new int[3];
		row = new int[3];
		alien = new String[3];
		rowPos[0]=40;
		rowPos[1]=144;
		rowPos[2]=248;
		block = 45;
		first = true;
		ic = ImageCache.getCache();
		rg = new Random();
		m_bc = BulletController.getBulletController();
		m_wm = WorldManager.getManager();
		loadWave();
	}
	public void control()
	{
		canvass++;
		if(canvass==2400)
			canvass=0;
		
		if(entering!=-1 && entering<row[0]+row[1]+row[2] && canvass%15==0)
		{
			Alien temp;
			if(entering<row[0])
			{
				temp = m_wm.createAlien(alien[0], new Point2D.Double(canvas.getWidth(),rowPos[0]), 180, enterList[entering]);
			}
			else if(entering<row[0]+row[1])
			{
				temp = m_wm.createAlien(alien[1], new Point2D.Double(-64,rowPos[1]), 0, enterList[entering]);
			}
			else
			{
				temp = m_wm.createAlien(alien[2], new Point2D.Double(canvas.getWidth(),rowPos[2]), 180, enterList[entering]);
			}
			add(temp);
			entering++;
		}
		
		if(canvass%15==0)
		{
			block+=90;
			if(block>=360)
				block-=360;
		}
		
		Iterator<Alien> iter = ents.iterator();
					
		while ( iter.hasNext() )
		{
			Alien e = iter.next();
			e.move();
			
			if(!e.isAlive())
			{
				iter.remove();
				continue;
			}
			
			if(rg.nextInt(20)==1)
			{
				//int angle=270;
				int angle;
				angle = 270;
				//TODO: make this a switch statement for angled bullets
				//TODO: make use of checking what kind of bullet the current enemy uses
				//		using the WorldManager class
				// m_bc.newBullet(e.getBulletType(), e.getX(), e.getY(), angle);
				WorldManager wm = WorldManager.getManager();
				m_bc.addBullet(wm.createBullet("bullet0", new Point(e.getX()+e.getImage().getWidth(null)/2, e.getY()+e.getImage().getHeight(null)), 2, angle), 2);
			}
		
			switch(e.getStatus())
			{
				case -1: //entering
					if(e.hasEntered() && e.getX()>e.getEnterPosition()-e.getSpeed()-1 && e.getX()<e.getEnterPosition()+e.getSpeed()+1)
					{
						e.setStatus(0);
						e.setSpeed(2);
						if(!first)
						{
							e.setDirection(45);
							block = 45;
							first = false;
						}
						else
							e.setDirection(block);
					}
					break;
				case 0: //normal shooting/flying
					switch(e.getMovement())
					{
						case BLOCK:
							if(canvass%15==0)
								e.setDirection(block);
							break;
						case DIAGONAL:
						case RANDOM:
						case CIRCLES:
					}
			}
		}
		if(ents.size()==0)
			loadWave();
	}
	public void loadWave()
	{
		Wave w = m_wm.next();
		if(w==null)
		{
			if(m_wm.nextLevel()==-1)
			{
				//TODO: Congrats, you win
				
			}
			else
			{
				//TODO: Go to some sort of store or upgrade area
			}
		}
		else
		{
			//init: enterList, row, alien, entering
			Debug.println("Loading wave");
			int t=0;
			enterList = new int[30];
			int healthBarWidth = canvas.getWidth() * 16 / AstroFrame.DEFAULT_WIDTH;
			int temp;
			for(int i=0;i<3;i++)
			{
				row[i] = w.numAliensInRow(i);
				alien[i] = w.alienIdentInRow(i);
				int imageWidth = m_wm.createAlien(alien[i], null, 0, 0).getImage().getWidth(null);
				int spaceTaken = imageWidth * row[i] + healthBarWidth;
				int padding = (canvas.getWidth() - spaceTaken) / (row[i]+1);
				switch(i)
				{
					case 0:
					case 2:
						temp = padding;
						for(int j=0;j<row[i];j++)
						{
							enterList[t] = temp + 20;
							t++;
							temp+=imageWidth+padding;
						}
						break;
					case 1:
						temp = canvas.getWidth() - healthBarWidth - padding - imageWidth;
						for(int j=0;j<row[i];j++)
						{
							enterList[t] = temp - 20;
							t++;
							temp-=(imageWidth+padding);
						}
				}
			}
			entering=0;
		}
	}
	public ArrayList<Alien> getEntities()
	{
		return ents;
	}
	public void add(Alien e)
	{
		ents.add(e);
	}
	public void remove(Alien e)
	{
		ents.remove(e);
	}
}